package cn.xjt.screenShare.controller;

import cn.xjt.screenShare.constant.EnumConstant;
import cn.xjt.screenShare.netty.NettyServer;
import cn.xjt.screenShare.netty.decoder.ImageDecoder;
import cn.xjt.screenShare.netty.share.CaptureImage;
import cn.xjt.screenShare.tcp.TcpServer;
import cn.xjt.screenShare.util.SystemUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import javafx.application.Platform;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class IndexController implements Initializable {
    public ComboBox<String> boxs;

    public Button btnLink;
    public Label msg;
    public TextField ipText;

    public MainController mainController;
    public AnchorPane anchor;
    public Pane serverLabel;

    public Boolean isNetty = true;


    public void setMainController(MainController mainController) {
        this.mainController = mainController;
    }

    private ExecutorService executorServices = Executors.newCachedThreadPool();

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        boxs.getItems().add("服务器(共享端)");//添加可选项
        boxs.getItems().add("客户端(接收端)");
        boxs.setStyle("-fx-font-size:15px");//修改字体大小
        btnLink.setDisable(true);
        serverLabel.setVisible(false);
        ipText.setPromptText("请输入局域网内服务器IP地址");
    }

    public void checked() {
        String value = boxs.getValue();
        btnLink.setDisable(false);
        if (value.equals(EnumConstant.TypeEnum.SERVER.getValue())){
            btnLink.setText("开始共享");
            String message = "你当前的ip地址为:"+ SystemUtil.getIpv4();
            msg.setText(message);
        } else if (value.equals(EnumConstant.TypeEnum.CLION.getValue())) {
            msg.setText("");
            serverLabel.setVisible(true);
            btnLink.setText("连接");
        }
    }

    /**
     * 主要的启动方法
     */
    public void btnAction(){
        if (btnLink.getText().equals("关闭连接") || btnLink.getText().equals("取消共享")){
            Platform.exit();
        }
        String value = boxs.getValue();
        if (value.equals(EnumConstant.TypeEnum.SERVER.getValue())){
            btnLink.setText("取消共享");
            new Thread(()->{
                if (isNetty){
                    NettyServer.getInstance().start();
                }else {
//                tcp有粘包半包问题，有待解决
//                    TcpServer.getInstance().start();
                }
            }).start();
        }else {
            btnLink.setText("关闭连接");
            Scene scene = anchor.getScene();
            Stage stage = (Stage) scene.getWindow();
            stage.setResizable(true);
            mainController.imageController.imageView.fitHeightProperty().bind(scene.heightProperty());
            mainController.imageController.imageView.fitWidthProperty().bind(scene.widthProperty());
            if (isNetty){
                nettyClient();
            }else {
//                tcp有粘包半包问题，有待解决
                tcpClient();
            }
        }
    }

    public void tcpClient(){
        System.out.println("客户端连接服务器...");
        Socket socket = null;
        try {
            socket = new Socket(ipText.getText(), EnumConstant.Port.SERVER.port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("已连接服务器...");
        mainController.indexController.anchor.setVisible(false);
        Socket finalSocket = socket;
        executorServices.submit(()->{
            InputStream inputStream = finalSocket.getInputStream();
            System.out.println("接受数据...");
            Platform.runLater(()->{
                mainController.imageController.imageView.setVisible(true);
                mainController.imageController.panda.setVisible(true);
            });
            while (true){
                int length = 0;
                byte[] bytes = new byte[50000];
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                while ((length=inputStream.read(bytes))>0){
                    os.write(bytes, 0,length);
                    if (inputStream.available()<=0){
                        break;
                    }
                }
                byte[] bytes1 = os.toByteArray();
                os.reset();
                Platform.runLater(()->{
                    System.out.println("设置图片..."+bytes1.length);
                    mainController.imageController.imageView.setImage(new Image(new ByteArrayInputStream(bytes1)));
                });
                Thread.sleep(40);
            }
        });
    }


    public void nettyClient(){
        mainController.indexController.anchor.setVisible(false);
        Platform.runLater(()->{
            mainController.imageController.imageView.setVisible(true);
            mainController.imageController.panda.setVisible(true);
        });
        Bootstrap handler = new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch){
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new ImageDecoder());
                        pipeline.addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) {
//								接受到图片数据
                                CaptureImage captureImage = (CaptureImage) msg;
                                System.out.println("接受数据==="+captureImage.getLength());
                                mainController.imageController.imageView.setImage(new Image(new ByteArrayInputStream(captureImage.getContent())));
                            }
                        });
                    }
                });
        try {
            handler.connect(new InetSocketAddress(ipText.getText(), EnumConstant.Port.SERVER.port)).sync().channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
